home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 44
/
Amiga Format CD44 (1999-08-26)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-10].iso
/
-in_the_mag-
/
workbench
/
netkeys
/
src
/
netkeys.e
< prev
Wrap
Text File
|
1999-07-28
|
8KB
|
297 lines
-> NetKeys v1.1 by Kyzer/CSG
-> transmits key and mouse input through network connection.
OPT PREPROCESS, OSVERSION=37
MODULE 'commodities', 'devices/inputevent', 'devices/pronet', 'dos/dos',
'exec/errors', 'exec/io', 'exec/nodes', 'exec/ports',
'libraries/commodities', '*args'
RAISE "CX" IF CreateCxObj()=NIL,
"LIB" IF OpenLibrary()=NIL,
"MEM" IF CreateMsgPort()=NIL,
"MEM" IF CreateIORequest()=NIL
#define VERSION '$VER: NetKeys 1.1 (16.11.98)'
CONST NETKEYS_PORT = 10350
ENUM EVT_HOTKEY, EVT_INPUT
#define PORTSIG(port) (Shl(1, port.sigbit))
#define APTR PTR TO LONG
#define TEMPLATE \
'MOUSE/S,CX_HOTKEY,CX_PRIORITY=CX_PRI/N,CX_ACTIVATE/S,MACHINE/N'
OBJECT myargs
usemouse -> should netkeys also send mouse events? (default FALSE)
cx_hotkey -> hotkey to activate/deactivate netkeys (default 'ctrl alt k')
cx_pri:APTR -> alternative CX priority (default 120)
cx_activate -> should netkeys start running on bootup? (default FALSE)
unit:APTR -> ProNET machine number/device unit to use (default 0)
ENDOBJECT
DEF args:PTR TO myargs,
cxport=NIL:PTR TO mp, broker=NIL, hotkey, keys, mouse, enabled,
netport=NIL:PTR TO mp, netio=NIL:PTR TO pnrequest, devport=NIL, open=-1
PROC main() HANDLE
DEF rdargs=NIL, ioerr
VOID VERSION
-> set up all the default arguments (as listed above) and parse the
-> arguments from CLI or WB
args := [FALSE, 'ctrl alt k', [120], FALSE, [0]]
IF (rdargs := readargs(TEMPLATE, args, wbmessage))=NIL THEN Raise("ARGS")
-> install a commodities broker to recieve commodity commands and act
-> as the base of our input stream processing
install_broker(args.cx_pri[])
-> open our connection to the ProNET network device
open_net(args.unit[], NETKEYS_PORT)
-> Install filters - one accepts only the hotkey (sends EVT_HOTKEY messages),
-> one grabs all keys, sends them to us (EVT_INPUT messages) and deletes
-> them, another optional one grabs all mouse-movements, and does likewise.
hotkey := install_filter(args.cx_hotkey, EVT_HOTKEY, 2)
IF CxObjError(hotkey) THEN Raise("CXK") -> if invalid hotkey
keys := install_filter(NIL, EVT_INPUT, 1)
SetFilterIX(keys, [IX_VERSION, IECLASS_RAWKEY, 0,0,0,0,0]:inputxpression)
IF args.usemouse
mouse := install_filter(NIL, EVT_INPUT, 0)
SetFilterIX(mouse, [IX_VERSION, IECLASS_RAWMOUSE, 0,0,0,0,0]:inputxpression)
ENDIF
-> start up our commodity, possibly start input-grabbing too
enable_netkeys(args.cx_activate)
mainloop()
EXCEPT DO
ioerr := IoErr()
-> disconnect from network
close_net()
-> remove our commodity
remove_broker()
IF rdargs THEN FreeArgs(rdargs)
SELECT exception
CASE "MEM"; msg(error(ERROR_NO_FREE_STORE))
CASE "NET"; msg(neterror(exceptioninfo))
CASE "CX"; msg('Error creating NetKeys commodity')
CASE "CXK"; msg('Invalid hotkey')
CASE "LIB"; msg('Error opening commodities.library')
DEFAULT; IF ioerr THEN msg(error(ioerr))
ENDSELECT
ENDPROC
CONST CTRLSIGS = SIGBREAKF_CTRL_C OR SIGBREAKF_CTRL_D OR SIGBREAKF_CTRL_E
PROC mainloop()
DEF sigs, m, id, type, evt:inputevent, quit=FALSE
REPEAT
sigs := Wait(CTRLSIGS OR PORTSIG(cxport) OR PORTSIG(netport))
WHILE m := GetMsg(cxport)
type := CxMsgType(m)
id := CxMsgID(m)
SELECT type
CASE CXM_IEVENT
CopyMem(CxMsgData(m), evt, SIZEOF inputevent)
ReplyMsg(m)
SELECT id
CASE EVT_INPUT; send_data(evt, SIZEOF inputevent)
CASE EVT_HOTKEY; enable_netkeys(IF enabled THEN FALSE ELSE TRUE)
ENDSELECT
CASE CXM_COMMAND
ReplyMsg(m)
-> standard Commodities behaviour
SELECT id
CASE CXCMD_DISABLE; ActivateCxObj(broker, FALSE)
CASE CXCMD_ENABLE; ActivateCxObj(broker, TRUE)
CASE CXCMD_KILL; quit := TRUE
CASE CXCMD_UNIQUE; quit := TRUE
ENDSELECT
ENDSELECT
ENDWHILE
-> throw away anything that arrives at our network port
-> as we do not care to recieve any data
clear_port(netport)
-> standard commodity behaviour
IF sigs AND SIGBREAKF_CTRL_C THEN quit := TRUE
IF sigs AND SIGBREAKF_CTRL_D THEN ActivateCxObj(broker, FALSE)
IF sigs AND SIGBREAKF_CTRL_E THEN ActivateCxObj(broker, TRUE)
UNTIL quit
ENDPROC
->-----------------------------------------------------------------------------
-> install_broker(): create a cxport and install the base commodity object
PROC install_broker(priority)
-> create a port to recieve CXMessages
cxport := CreateMsgPort()
-> install a broker in the commodities network
-> the broker says we have no 'user interface', and we must not be
-> run more than once. If we are, the other copy of us is notified,
-> and will quit itself.
cxbase := OpenLibrary('commodities.library', 37)
broker := CxBroker([
NB_VERSION, 0,
'NetKeys',
'ProNET netkeys/netmouse',
'Use keyboard/mouse over network',
NBU_UNIQUE OR NBU_NOTIFY, 0, priority, 0, cxport, 0
]:newbroker, NIL)
IF broker = NIL THEN Raise() -> silent error if we can't make a broker
ENDPROC
-> install_filter(expression, event_type, pri): install filter which
-> sends all input matching the expression string to our cxport, with
-> type event_type, then deletes the input from the input stream.
->
PROC install_filter(expression, event_type, priority)
DEF filter
-> attach a new filter to our broker with certain priority
AttachCxObj(broker, filter := CxFilter(expression))
SetCxObjPri(filter, priority)
-> our filter will send us then delete any matching input
AttachCxObj(filter, CxSender(cxport, event_type))
AttachCxObj(filter, CxTranslate(NIL))
ENDPROC filter
-> remove_broker(): remove our commodity from the system
PROC remove_broker()
-> remove all our CXObjects and their broker
IF broker THEN DeleteCxObjAll(broker)
-> close commodities library
CloseLibrary(cxbase)
-> throw away any remaining CXMessages at our cxport, then delete it
IF cxport
clear_port(cxport)
DeleteMsgPort(cxport)
ENDIF
ENDPROC
-> enable_netkeys(state): TRUE enables netkeys/netmouse, FALSE disables it.
PROC enable_netkeys(state)
enabled := state
IF args.usemouse THEN ActivateCxObj(mouse, state)
ActivateCxObj(keys, state)
ActivateCxObj(hotkey, TRUE)
ActivateCxObj(broker, TRUE)
ENDPROC
->-----------------------------------------------------------------------------
CONST INVALID_PORT = -999
PROC open_net(unit, port)
IF (port < 0) OR (port > $7fff) THEN Throw("NET", INVALID_PORT)
netio := CreateIORequest(devport := CreateMsgPort(), SIZEOF pnrequest)
netio.msgport := (netport := CreateMsgPort())
netio.netsourceport := port
netio.netdestport := port
IF open := OpenDevice('pronet.device', unit, netio, 0) THEN Throw("NET", open)
ENDPROC
PROC close_net()
IF open = 0 THEN CloseDevice(netio)
IF netport
clear_port(netport)
DeleteMsgPort(netport)
ENDIF
IF netio THEN DeleteIORequest(netio)
IF devport
clear_port(devport)
DeleteMsgPort(devport)
ENDIF
ENDPROC
PROC send_data(data, len)
DEF err
netio.ioreq.command := CMD_WRITE
netio.data := data
netio.length := len
IF err := DoIO(netio) THEN Throw("NET", err)
ENDPROC
-> names for network errors
PROC neterror(err)
SELECT err
CASE IOERR_OPENFAIL; RETURN 'can\at open pronet.device'
CASE INVALID_PORT; RETURN 'invalid port number'
CASE PNDERR_PORTEXISTS; RETURN 'port already in use'
CASE PNDERR_DRIVERTROUBLE; RETURN 'error starting network driver'
CASE PNDERR_UNIT_NOT_DEFINED; RETURN 'invalid machine number'
CASE PNDERR_DESTINATION_GONE; RETURN 'network write error'
DEFAULT; RETURN 'network error'
ENDSELECT
ENDPROC
->-----------------------------------------------------------------------------
-> message-printer for WB and shell
PROC msg(msg, args=NIL)
IF wbmessage
EasyRequestArgs(NIL, NEW [20, 0, 'NetKeys', msg, 'Quit'], 0, args)
ELSE
Vprintf(msg, args); PutStr('\n')
ENDIF
ENDPROC
-> returns string form of DOS Fault. Can prepend header.
PROC error(error, header=NIL)
DEF x
SetStr(x := String((IF header THEN StrLen(header) ELSE 0) + FAULT_MAX + 2),
Fault(error, header, x, StrMax(x))
)
ENDPROC x
-> removes all messages at a port
PROC clear_port(port)
DEF m; WHILE m := GetMsg(port) DO ReplyMsg(m)
ENDPROC